import MBCore from "./mb_core";
import MBKeepAliveDaemon from './mb_daemon_keep_alive'
import MBDataReciever from './mb_data_reciever'

class MBSocketProvider {
    private localSocket: any = null;
    private connectionDoneCallback: any = null;

    public setConnectionDoneCallback(callback: any): void {
        this.connectionDoneCallback = callback;
    }


    public resetLocalSocket() {
        try {
            this.closeLocalSocket(true);
            this.tryConnectToHost();
            return this.localSocket || null;
        } catch (e) {
            console.error(`重置localSocket时出错，原因是：${e}`);
            this.closeLocalSocket(true);
            return null;
        }
    }


    public tryConnectToHost() {

        var done = false;
        var that = this;

        try {
            if (window.WebSocket) {
                this.localSocket = new WebSocket(MBCore.getWebsocketUrl());// "ws://192.168.99.190:7080/websocket"
                this.localSocket.onopen = (event: any) => {
                    if (that.connectionDoneCallback) {
                        that.connectionDoneCallback(true);
                        that.connectionDoneCallback = null;
                    }
                };

                this.localSocket.onclose = (evt: any) => {
                    if (MBCore.isConnectedToServer()) {
                        MBKeepAliveDaemon.notifyConnectionLost();
                    }
                }


                this.localSocket.onerror = (evt: any) => {
                    that.closeLocalSocket(true);
                };

                this.localSocket.onmessage = (event: any) => {
                    let protocalJsonStr = (event ? (event.data ? event.data : null) : null);
                    // 读取收到的数据 Protocal 对象
                    let pFromServer = (protocalJsonStr ? JSON.parse(protocalJsonStr) : null);
                    // 进入消息调度和处理逻辑
                    MBDataReciever.handleProtocal(pFromServer);
                };

                done = true;
            }
        }
        catch (e) {
            console.log("连接Server(" + MBCore.getWebsocketUrl() + ")失败：");
        }

        return done;
    }


    isLocalSocketReady() {
        return this.localSocket != null && this.localSocket.readyState === 1;
    }

    getLocalSocket() {
        if (this.isLocalSocketReady()) {
            return this.localSocket;
        }
        else {
            return this.resetLocalSocket();
        }
    }


    closeLocalSocket(silentClose?: any) {
        let thatSocket = this.localSocket;
        if (this.localSocket) {
            try {
                // close前会清掉为此socket实例设置的各种回调，确保close时不会触发这些回调（比如：在掉线重连场景下，close
                // 掉前一个旧的失效socket就不会错误地触发这些回调，而且还因为close是异步的，从而会引发一系列不可预测的行为）
                if (silentClose) {
                    thatSocket.onerror = null;
                    thatSocket.onclose = null;
                    thatSocket.onopen = null;
                    thatSocket.onmessage = null;

                }

                // 真正开始关闭socket了
                thatSocket.close();
                // 确保本次清理的socket实例是本方法初始时的那个实例（排除因异步等原因this.localSocket被重新设置后又在此被错误地置空，那就坑爹了）
                if (Object.is(thatSocket, this.localSocket)) {
                    this.localSocket = null;
                }
            }
            catch (e) {
                console.log("在closeLocalSocket方法中试图释放localSocket资源时：", e);
            }
        }
        else {
            console.log("Socket处于未初化状态（可能是您还未登陆），无需关闭。")
        }
    }
}

export default new MBSocketProvider();